package cn.faifai.framework.jna;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
/**
 * JNA（Java Native Access）是一个开源库，它允许Java程序直接调用本地共享库中的函数，
 * 而不需要编写任何JNI（Java Native Interface）代码或额外的胶水代码。使用JNA的过程大致如下：
 *
 * 1. **添加JNA依赖**：首先需要确保你的项目中包含了JNA库。如果你使用的是Maven构建工具，可以在`pom.xml`文件中加入相应的依赖项。
 *
 * 2. **定义接口**：创建一个接口来描述你想要访问的本地库及其方法。这个接口需要继承自`com.sun.jna.Library`接口，
 *    并且每个方法对应于原生库中的一个函数。你需要为这些方法指定正确的参数类型和返回类型，以匹配原生函数的签名。
 *
 * 3. **加载本地库**：使用`com.sun.jna.Native.load()`方法加载你想要使用的本地库。这将返回你在第二步中定义的接口的一个实现。
 *
 * 4. **调用本地方法**：通过调用第三步得到的对象上的方法来间接调用原生库中的函数。
 *
 * 5. **处理数据结构**：如果原生库中的函数涉及到复杂的数据结构（如结构体），你需要在Java中创建对应的类来表示这些结构体，
 *    并使用JNA提供的注解（如`@Structure.FieldOrder`）来描述它们的内存布局。
 *
 * 简单来说，JNA的工作流程涉及到了解系统本地函数、在Java中描述这些函数及相关的数据结构（如结构体），
 * 然后通过JNA进行调用。不过，JNA简化了这一过程，因为它不需要手动编写JNI代码，减少了开发者的负担。
 *
 * 需要注意的是，在使用JNA时，确保本地库与你的Java应用程序兼容，包括操作系统、架构以及编译器选项等都需要考虑。
 * 此外，由于直接调用了本地代码，错误处理和异常管理也是不可忽视的部分。
 */

// 定义 Kernel32 接口
public interface faifaiKernel32 extends StdCallLibrary {
    faifaiKernel32 INSTANCE = Native.load("Kernel32", faifaiKernel32.class);

    /**
     * 结构体声明
     */
    class BY_HANDLE_FILE_INFORMATION extends Structure {
        public int dwFileAttributes;
        public WinNT.FILETIME ftCreationTime;
        public WinNT.FILETIME ftLastAccessTime;
        public WinNT.FILETIME ftLastWriteTime;
        public int dwVolumeSerialNumber;
        public int nFileSizeHigh;
        public int nFileSizeLow;
        public int nNumberOfLinks;
        public int nFileIndexHigh;
        public int nFileIndexLow;

        @Override
        protected java.util.List<String> getFieldOrder() {
            return java.util.Arrays.asList(
                    "dwFileAttributes", "ftCreationTime", "ftLastAccessTime",
                    "ftLastWriteTime", "dwVolumeSerialNumber", "nFileSizeHigh",
                    "nFileSizeLow", "nNumberOfLinks", "nFileIndexHigh", "nFileIndexLow"
            );
        }
    }

    /**
     * 函数声明
     */
    // 打开文件句柄
    WinNT.HANDLE CreateFileA(
            String lpFileName,
            WinDef.DWORD dwDesiredAccess,
            WinDef.DWORD dwShareMode,
            Pointer lpSecurityAttributes,
            WinDef.DWORD dwCreationDisposition,
            WinDef.DWORD dwFlagsAndAttributes,
            Pointer hTemplateFile
    );

    // 获取文件信息
    boolean GetFileInformationByHandle(
            WinNT.HANDLE hFile,
            BY_HANDLE_FILE_INFORMATION lpFileInformation
    );

    // 关闭句柄
    boolean CloseHandle(WinNT.HANDLE hObject);

    // 监控文件变化
    boolean ReadDirectoryChangesW(
            WinNT.HANDLE hDirectory,
            Pointer lpBuffer,
            WinDef.DWORD nBufferLength,
            boolean bWatchSubtree,
            WinDef.DWORD dwNotifyFilter,
            IntByReference lpBytesReturned,
            Pointer lpOverlapped,
            Pointer lpCompletionRoutine);
}
